#include "GameManager.h"
#include "RandomSystem.h"
#include "GameSettings.h"
#include "AuctionManager.h"
#include "PeopleManager.h"
#include "TeamManager.h"
#include "LeagueManager.h"
#include "UserManager.h"
#include "NameManager.h"
#include "MatchManager.h"
#include "Events.h"
#include "ZStream.h"
#include "GameAi.h"
#include "User.h"

#ifndef DARIO
#include "Calendar.h"
#endif

GameManager::GameManager()
{
	m_seed = InitRandomSystem();

	m_settings = new Settings;
	m_settings->Load("./settings.txt");

	m_nameManager = new NameManager;
	m_auctionManager = new AuctionManager(this);
	m_teamManager = new TeamManager(this);
	m_peopleManager = new PeopleManager(this);
	m_leagueManager = new LeagueManager(this);
	m_userManager = new UserManager(this);
	m_ai = new GameAI(this);
	m_matchEventGenerator = new EventGenerator("match_events.txt");
	m_matchManager = new MatchManager(this);
#ifndef DARIO
	m_calendar = new Calendar();
#endif
}

GameManager::~GameManager()
{
	Clear();

	delete m_matchEventGenerator;
	delete m_ai;
	delete m_userManager;
	delete m_leagueManager;
	delete m_peopleManager;
	delete m_teamManager;
	delete m_auctionManager;
	delete m_nameManager;
	delete m_settings;
	delete m_matchManager;
#ifndef DARIO
	delete m_calendar;
#endif
}

void GameManager::Initialize()
{
	ZStream file;

	GetPeopleMgr().Initialize();
	
	GetTeamMgr().Initialize();

	file.Open("./leagueSettings.txt", STD::ios_base::in);
	LeagueManagerSettings settings;
	settings.Deserialize(file);
	file.Close();
	GetLeagueMgr().Initialize(settings);

	GetAI().AssignPlayersOnTeams(GetLeagueMgr().GetLeagues(false));
	
#ifndef DARIO
	m_calendar->Initialize();
#endif

	GetPeopleMgr().CreateFreePeople(100, 50);
}

//void GameManager::DailyUpdate()
//{
//	...
//}

void GameManager::PreMatchUpdate(const bool i_doNotPrompt)
{
	// Pre-OldMatch AI Update: market and formations
	GetAI().PreMatchUpdate(i_doNotPrompt);
}

void GameManager::Update(const bool i_doNotPrompt)
{	
	// League Manager Update
	GetLeagueMgr().Update(i_doNotPrompt);
}

void GameManager::PostMatchUpdate(const bool i_doNotPrompt)
{
	// Team Manager Update: money (now in match, to be moved)
	GetTeamMgr().Update();
	
	// People Manager Update: free players must be updated (fatiguee update, inj update)
	GetPeopleMgr().Update();

	// People Offers Resolution
	GetAuctionMgr().Dispatch(i_doNotPrompt);
	
	// Post-OldMatch AI Update: make formations (not necessary, just to debug-view how the team)
	GetAI().PostMatchUpdate();
}

void GameManager::Simulate(const bool i_doNotPrompt)
{
	//clock_t clock0 = clock();
	PreMatchUpdate(i_doNotPrompt);

	//clock_t clock1 = clock();
	//clock_t time1 = clock1 - clock0;
	Update(i_doNotPrompt);

	//clock_t clock2 = clock();
	//clock_t time2 = clock2 - clock1;
	PostMatchUpdate(i_doNotPrompt);

	//clock_t clock3 = clock();
	//clock_t time3 = clock3 - clock2;
	if(!i_doNotPrompt)
		system("pause");
	//else
	//	STD::cout << time1 << "  " << time2 << "  " << time3 << STD::endl;
}

void GameManager::EndSeason(const bool i_doNotPrompt, STD::stringstream& o_message)
{
	GetLeagueMgr().EndSeasonUpdate(i_doNotPrompt, o_message);
	GetTeamMgr().EndSeasonUpdate(o_message);
	GetPeopleMgr().EndSeasonUpdate(i_doNotPrompt, o_message);
	GetPeopleMgr().CreateFreePeople(100, 10);

	GetLeagueMgr().RestartLeagues(); // must be done here, because of teams bankrupt
}

void GameManager::Clear()
{
	GetLeagueMgr().Clear();
	GetPeopleMgr().Clear();
	GetTeamMgr().Clear();
	GetNameMgr().Clear();
	GetAuctionMgr().Clear();
	GetUserMgr().Clear();
}

void GameManager::Restart()
{
	Clear();

	Initialize();
}

bool GameManager::Load(const char* const filename)
{
	ZStream file;

	if(!file.Open(filename, STD::fstream::in))
		return false;

	Clear();

	file.ReadAttribute(m_seed);

	LeagueManagerSettings settings;
	settings.Deserialize(file);
	GetLeagueMgr().Initialize(settings);
	GetLeagueMgr().Deserialize(file);

	GetPeopleMgr().Initialize();
	GetPeopleMgr().Deserialize(file);

	GetTeamMgr().Initialize();
	GetTeamMgr().Deserialize(file);

	GetUserMgr().Deserialize(file);

	GetAuctionMgr().Deserialize(file);

	return true;
}

bool GameManager::Save(const char* const filename)
{
	ZStream file;
	if(!file.Open(filename, STD::fstream::out | STD::fstream::trunc))
		return false;

	file.WriteAttribute("Seed", m_seed);

	GetLeagueMgr().GetSettings().Serialize(file);
	GetLeagueMgr().Serialize(file);

	GetPeopleMgr().Serialize(file);

	GetTeamMgr().Serialize(file);

	GetUserMgr().Serialize(file);

	GetAuctionMgr().Serialize(file);

	return true;
}

